/*
 *  Licensed under the Apache License, Version 2.0 (the "License");
 *  you may not use this file except in compliance with the License.
 *  You may obtain a copy of the License at
 * 
 *       http://www.apache.org/licenses/LICENSE-2.0
 * 
 *  Unless required by applicable law or agreed to in writing, software
 *  distributed under the License is distributed on an "AS IS" BASIS,
 *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 *  See the License for the specific language governing permissions and
 *  limitations under the License.
 *  under the License.
 */
package au.com.domlogic.pvc.core.element;

import au.com.domlogic.pvc.core.node.CompositeNode;
import org.w3c.dom.Attr;
import org.w3c.dom.DOMException;
import org.w3c.dom.Element;
import org.w3c.dom.NodeList;
import org.w3c.dom.TypeInfo;

/**
 * A simple implementation of {@link Element} by Composition.
 * @author Domenic Figliomeni
 */
public class CompositeElement extends CompositeNode implements Element {

    public CompositeElement(Element anElement) {
        super(anElement);
    }

    protected CompositeElement() {
    }

    protected Element getUnderlyingElement() {
        return (Element) this.getUnderlyingNode();
    }

    protected void setUnderlyingElement(Element element) {
        this.setUnderlyingNode(element);
    }

    /**
     *
     * @see Element#getAttribute(java.lang.String)
     */
    @Override
    public String getAttribute(String arg0) {
        return this.getUnderlyingElement().getAttribute(arg0);
    }

    /**
     *
     * @see Element#getAttributeNS(java.lang.String, java.lang.String)
     */
    @Override
    public String getAttributeNS(String arg0, String arg1) throws DOMException {
        return this.getUnderlyingElement().getAttributeNS(arg0, arg1);
    }

    /**
     *
     * @see Element#getAttributeNode(java.lang.String)
     */
    @Override
    public Attr getAttributeNode(String arg0) {
        return this.getUnderlyingElement().getAttributeNode(arg0);
    }

    /**
     *
     * @see Element#getAttributeNodeNS(java.lang.String, java.lang.String)
     */
    @Override
    public Attr getAttributeNodeNS(String arg0, String arg1) throws DOMException {
        return this.getUnderlyingElement().getAttributeNodeNS(arg0, arg1);
    }

    /**
     *
     * @see Element#getElementsByTagName(java.lang.String)
     */
    @Override
    public NodeList getElementsByTagName(String arg0) {
        return this.getUnderlyingElement().getElementsByTagName(arg0);
    }

    /**
     *
     * @see Element#getElementsByTagNameNS(java.lang.String, java.lang.String)
     */
    @Override
    public NodeList getElementsByTagNameNS(String arg0, String arg1) throws DOMException {
        return this.getUnderlyingElement().getElementsByTagNameNS(arg0, arg1);
    }

    /**
     *
     * @see Element#getSchemaTypeInfo()
     */
    @Override
    public TypeInfo getSchemaTypeInfo() {
        return this.getUnderlyingElement().getSchemaTypeInfo();
    }

    /**
     *
     * @see Element#getTagName()
     */
    @Override
    public String getTagName() {
        return this.getUnderlyingElement().getTagName();
    }

    /**
     *
     * @see Element#hasAttribute(java.lang.String)
     */
    @Override
    public boolean hasAttribute(String arg0) {
        return this.getUnderlyingElement().hasAttribute(arg0);
    }

    /**
     *
     * @see Element#hasAttributeNS(java.lang.String, java.lang.String)
     */
    @Override
    public boolean hasAttributeNS(String arg0, String arg1) throws DOMException {
        return this.getUnderlyingElement().hasAttributeNS(arg0, arg1);
    }

    /**
     *
     * @see Element#removeAttribute(java.lang.String)
     */
    @Override
    public void removeAttribute(String arg0) throws DOMException {
        this.getUnderlyingElement().removeAttribute(arg0);
    }

    /**
     *
     * @see Element#removeAttributeNS(java.lang.String, java.lang.String)
     */
    @Override
    public void removeAttributeNS(String arg0, String arg1) throws DOMException {
        this.getUnderlyingElement().removeAttributeNS(arg0, arg1);
    }

    /**
     * If arg0 is a CompositeAttr, then we need to use the underlying attr
     * as it is the one with the same implementation as the document.
     *
     * @see Element#removeAttributeNode(org.w3c.dom.Attr)
     */
    @Override
    public Attr removeAttributeNode(Attr arg0) throws DOMException {
        return this.removeAttributeNode(
                (Attr) CompositeNode.getRealNode(arg0));
    }

    /**
     *
     * @see Element#setAttribute(java.lang.String, java.lang.String)
     */
    @Override
    public void setAttribute(String arg0, String arg1) throws DOMException {
        this.getUnderlyingElement().setAttribute(arg0, arg1);
    }

    /**
     *
     * @see Element#setAttributeNS(java.lang.String, java.lang.String, java.lang.String)
     */
    @Override
    public void setAttributeNS(String arg0, String arg1, String arg2) throws DOMException {
        this.getUnderlyingElement().setAttributeNS(arg0, arg1, arg2);
    }

    /**
     * If arg0 is a CompositeAttr, then we need to use the underlying attr
     * as it is the one with the same implementation as the document.
     *
     * @see Element#setAttributeNode(org.w3c.dom.Attr)
     */
    @Override
    public Attr setAttributeNode(Attr arg0) throws DOMException {
        return this.getUnderlyingElement().setAttributeNode(
                (Attr) CompositeNode.getRealNode(arg0));
    }

    /**
     * If arg0 is a CompositeAttr, then we need to use the underlying attr
     * as it is the one with the same implementation as the document.
     *
     * @see Element#setAttributeNodeNS(org.w3c.dom.Attr)
     */
    @Override
    public Attr setAttributeNodeNS(Attr arg0) throws DOMException {
        return this.getUnderlyingElement().setAttributeNodeNS(
                (Attr) CompositeNode.getRealNode(arg0));
    }

    /**
     *
     * @see Element#setIdAttribute(java.lang.String, boolean)
     */
    @Override
    public void setIdAttribute(String arg0, boolean arg1) throws DOMException {
        this.getUnderlyingElement().setIdAttribute(arg0, arg1);
    }

    /**
     *
     * @see Element#setIdAttributeNS(java.lang.String, java.lang.String, boolean)
     */
    @Override
    public void setIdAttributeNS(String arg0, String arg1, boolean arg2) throws DOMException {
        this.getUnderlyingElement().setIdAttributeNS(arg0, arg1, arg2);
    }

    /**
     * If arg0 is a CompositeAttr, then we need to use the underlying attr
     * as it is the one with the same implementation as the document.
     *
     * @see Element#setIdAttributeNode(org.w3c.dom.Attr, boolean) 
     */
    @Override
    public void setIdAttributeNode(Attr arg0, boolean arg1) throws DOMException {
        this.getUnderlyingElement().setIdAttributeNode(
                (Attr) CompositeNode.getRealNode(arg0), arg1);
    }
}
